using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AnimationProcesser
{
    #region Variables
    Animator _mAnimator;

    AnimationObject _mCurAnimationSet;
    AnimationMatchTargetObject _mCurAnimationMatchSet;

    int _mCurAnimationLayer;

    // -------------------------------------------------------------------------------- //

    string _mLastStateAnimationName;
    string _mCurStateAnimationName;

    AnimationObject.StateAnimationBlend _mCurBlendAnimation = new AnimationObject.StateAnimationBlend();

    bool _mBlending;

    // -------------------------------------------------------------------------------- //

    string _mCurPlayableAnimationName;

    AnimationObject.PlayableAnimation _mCurPlayableAnimation = new AnimationObject.PlayableAnimation();

    bool _mInsertingPlayable;
    bool _mPlayablePlaying;
    bool _mInsertPlayableFirst;

    // -------------------------------------------------------------------------------- //

    #endregion

    #region Init
    public void Init()
    {
        _mLastStateAnimationName = null;
    }
    #endregion

    #region Process Methods
    public void ProcessAnimation()
    {
        // ����״̬���
        if ((_mLastStateAnimationName != _mCurStateAnimationName) && !_mInsertPlayableFirst)
        {
            for (int i = 0; i < _mCurAnimationSet.stateAnimationBlends.Count + 1; i++)
            {
                // ��ǰ�л�״̬����������
                if (i == _mCurAnimationSet.stateAnimationBlends.Count)
                {
                    _mAnimator.CrossFadeInFixedTime(_mCurStateAnimationName.ToString(), _mCurAnimationSet.animationGlobalTransitionDuration, _mCurAnimationLayer);

                    _mLastStateAnimationName = _mCurStateAnimationName;
                    break;
                }
                // ��ǰ�л�״̬��������
                if ((_mLastStateAnimationName == _mCurAnimationSet.stateAnimationBlends[i].fromAnimation) && (_mCurStateAnimationName == _mCurAnimationSet.stateAnimationBlends[i].toAnimation))
                {
                    // �����Ź��ɶ���
                    if (_mCurAnimationSet.stateAnimationBlends[i].blendAnimation == "Null")
                    {
                        _mAnimator.CrossFadeInFixedTime(_mCurAnimationSet.stateAnimationBlends[i].toAnimation.ToString(), _mCurAnimationSet.stateAnimationBlends[i].fromBlendAnimationTransitionDuration, _mCurAnimationLayer, _mCurAnimationSet.stateAnimationBlends[i].fromBlendAnimationTransitionOffset);
                    }
                    // ���Ź��ɶ���
                    else
                    {
                        _mAnimator.CrossFadeInFixedTime(_mCurAnimationSet.stateAnimationBlends[i].blendAnimation, _mCurAnimationSet.stateAnimationBlends[i].fromBlendAnimationTransitionDuration, _mCurAnimationLayer-_mCurAnimationLayer, _mCurAnimationSet.stateAnimationBlends[i].fromBlendAnimationTransitionOffset);

                        _mCurBlendAnimation = _mCurAnimationSet.stateAnimationBlends[i];

                        _mBlending = true;
                    }

                    _mLastStateAnimationName = _mCurStateAnimationName;
                    break;
                }
            }
        }

        // ��������
        if (_mInsertingPlayable)
        {
            for (int i = 0; i < _mCurAnimationSet.playableAnimations.Count + 1; i++)
            {
                // û�����øò��붯��
                if (i == _mCurAnimationSet.playableAnimations.Count)
                {
                    AnimationObject.PlayableAnimation tmpPlayable = new AnimationObject.PlayableAnimation();
                    tmpPlayable.animationName = _mCurPlayableAnimationName;
                    tmpPlayable.playableName = _mCurPlayableAnimationName;

                    _mCurAnimationSet.playableAnimations.Add(tmpPlayable);

                    _mCurPlayableAnimation = _mCurAnimationSet.playableAnimations[i];
                    break;
                }
                // �����øò��붯��
                if (_mCurAnimationSet.playableAnimations[i].animationName == _mCurPlayableAnimationName)
                {
                    _mCurPlayableAnimation = _mCurAnimationSet.playableAnimations[i];
                    break;
                }
            }

            // ������붯������ɶ�������Ȩ
            _mInsertPlayableFirst = _mCurPlayableAnimation.animationPriority > 0;

            _mAnimator.CrossFadeInFixedTime(_mCurPlayableAnimation.animationName, _mCurPlayableAnimation.fromPlayableAnimationTransitionDuration, _mCurAnimationLayer, _mCurPlayableAnimation.fromPlayableAnimationTransitionOffset);

            _mInsertingPlayable = false;
            _mPlayablePlaying = true;
        }

        // �ж����붯���Ƿ񲥷���ϲ����ص�ǰ״̬����
        if (_mPlayablePlaying && _mAnimator.GetCurrentAnimatorStateInfo(_mCurAnimationLayer).IsName(_mCurPlayableAnimation.animationName))
        {
            //                                                                                                                                         //TO DO
            if (_mAnimator.GetCurrentAnimatorStateInfo(_mCurAnimationLayer).normalizedTime > 1f - _mCurPlayableAnimation.toPlayableAnimationTransitionDuration)
            {
                _mAnimator.CrossFadeInFixedTime(_mCurStateAnimationName, _mInsertPlayableFirst ? _mCurAnimationSet.animationGlobalTransitionDuration : _mCurPlayableAnimation.toPlayableAnimationTransitionDuration, _mCurAnimationLayer, _mCurPlayableAnimation.toPlayableAnimationTransitionOffset);
                _mPlayablePlaying = false;

                // ���������ȼ����ڹ������ȼ�
                if (_mInsertPlayableFirst)
                {
                    // �������ȼ�
                    _mInsertPlayableFirst = false;
                }
            }
        }

        // �ж���϶����Ƿ񲥷���ϲ����ص�ǰ״̬����
        if (_mBlending && _mAnimator.GetCurrentAnimatorStateInfo(_mCurAnimationLayer).IsName(_mCurBlendAnimation.blendAnimation) && !_mInsertPlayableFirst)
        {
            //                                                                                                                                         //TO DO
            if (_mAnimator.GetCurrentAnimatorStateInfo(_mCurAnimationLayer).normalizedTime > 1f - _mCurBlendAnimation.toBlendAnimationTransitionDuration)
            {
                _mAnimator.CrossFadeInFixedTime(_mCurStateAnimationName.ToString(), _mCurBlendAnimation.toBlendAnimationTransitionDuration, _mCurAnimationLayer, _mCurBlendAnimation.toBlendAnimationTransitionOffset);
                _mBlending = false;
            }
        }
    }
    #endregion

    #region Match Methods
    public void MatchAnimaionTarget()
    {
        if (_mCurAnimationMatchSet)
        {
            for(int i = 0; i < _mCurAnimationMatchSet.animationTargetMatches.Count; i++)
            {
                if(_mAnimator.GetCurrentAnimatorStateInfo(_mCurAnimationLayer).IsName(_mCurAnimationMatchSet.animationTargetMatches[i].animationName))
                {
                    if (!_mAnimator.IsInTransition(_mCurAnimationLayer))
                    {
                        AnimationMatchTargetObject.AnimationTargetMatch tmpMatch = _mCurAnimationMatchSet.animationTargetMatches[i];
                        _mAnimator.MatchTarget(tmpMatch.matchPostion, tmpMatch.matchRotation, tmpMatch.avatarTarget, new MatchTargetWeightMask(tmpMatch.postionWeight, tmpMatch.rotationWeight), tmpMatch.startTime, tmpMatch.targetTime);
                    }
                }
            }
        }
    }
    #endregion

    #region Register Methods
    public void MainRegister(Animator animator, AnimationObject animationSet, int animationLayer)
    {
        _mAnimator = animator;
        _mCurAnimationSet = animationSet;
        _mCurAnimationLayer = animationLayer;
    }

    public void MatchTargetRegister(AnimationMatchTargetObject animationMatchSet)
    {
        _mCurAnimationMatchSet = animationMatchSet;
    }
    #endregion

    #region Play Methods
    public void PlayStateAnimation(string animationName)
    {
        _mCurStateAnimationName = animationName;   
    }

    public void PlayPlayableAnimation(string animationName) 
    {
        _mCurPlayableAnimationName = animationName;
        _mInsertingPlayable = true;
    }

    public void SetTargetMatch(string animationName, Vector3 targetPostion, Quaternion targetRotation)
    {
        if (_mCurAnimationMatchSet)
        {
            for (int i = 0; i < _mCurAnimationMatchSet.animationTargetMatches.Count; i++)
            {
                if(animationName == _mCurAnimationMatchSet.animationTargetMatches[i].animationName)
                {
                    _mCurAnimationMatchSet.animationTargetMatches[i].matchPostion = targetPostion;
                    _mCurAnimationMatchSet.animationTargetMatches[i].matchRotation = targetRotation;
                }
            }
        }
    }
    #endregion
}
